import _ from "lodash";
import Mock from "mockjs";
import {MockConfig, MockerStyle, MockMode, RequestConfig} from "./http-client-type.js";
import {defaultCustomRequestConfig} from "./http-client-default-config.js";
import handleResponseFulfilled from "./handle-response-fulfilled.js";
import HttpClient from "./http-client.js";

export default {
  isMocked(
      requestConfig: RequestConfig<any>,
      mockConfig: MockConfig
  ): boolean {
    if (mockConfig.mode === MockMode.SERVER) {
      return false;
    }

    if (mockConfig.mode === MockMode.MOCKER) {
      return true;
    }

    // 优先考虑请求的mock配置，然后考虑全局的mock配置
    if (requestConfig?.mocked) {
      return typeof requestConfig.mocked === "function"
          ? requestConfig.mocked()
          : requestConfig.mocked;
    }

    return typeof mockConfig.mixModeDefaultMocked === "function"
        ? mockConfig.mixModeDefaultMocked()
        : mockConfig.mixModeDefaultMocked;
  },
  mockStyle(
      requestConfig: RequestConfig<any>,
      mockConfig: MockConfig
  ): MockerStyle {
    // 优先考虑请求的mock配置，然后考虑全局的mock配置
    if (requestConfig?.mockServerBaseUrl || requestConfig?.mockTemplate) {
      return requestConfig.mockServerBaseUrl
          ? MockerStyle.SERVER
          : MockerStyle.TEMPLATE;
    }

    return mockConfig.defaultMockServerBaseUrl
        ? MockerStyle.SERVER
        : MockerStyle.TEMPLATE;
  },
  mockServerBaseUrl(
      requestConfig: RequestConfig<any>,
      mockConfig: MockConfig,
  ): string {
    // 优先考虑请求的mock配置，然后考虑全局的mock配置
    if (requestConfig?.mockServerBaseUrl) {
      return typeof requestConfig.mockServerBaseUrl === "function"
          ? requestConfig.mockServerBaseUrl()
          : requestConfig.mockServerBaseUrl;
    }

    return typeof mockConfig.defaultMockServerBaseUrl === "function"
        ? mockConfig.defaultMockServerBaseUrl()
        : mockConfig.defaultMockServerBaseUrl;
  },
  isTemplateMock(
      requestConfig: RequestConfig<any>,
      mockConfig: MockConfig,
  ): boolean {
    return (
        this.isMocked(requestConfig, mockConfig) &&
        this.mockStyle(requestConfig, mockConfig) === MockerStyle.TEMPLATE
    );
  },
  mockTemplate(
      requestConfig: RequestConfig<any>,
      mockConfig: MockConfig,
  ): string | object {
    // 优先考虑请求的mock配置，然后考虑全局的mock配置
    if (requestConfig?.mockTemplate) {
      return typeof requestConfig.mockTemplate === "function"
          ? requestConfig.mockTemplate()
          : requestConfig.mockTemplate;
    }

    return typeof mockConfig.defaultMockTemplate === "function"
        ? mockConfig.defaultMockTemplate()
        : mockConfig.defaultMockTemplate;
  },
  createMockTemplateAxiosResponse(
      data: any,
      requestConfig: RequestConfig<any>
  ) {
    return {
      data: data,
      status: 200,
      statusText: "OK",
      headers: {"content-type": "application/json; charset=utf-8"},
      config: _.defaultsDeep(requestConfig, defaultCustomRequestConfig),
    };
  },
  mockTemplateResponse(
      requestConfig: RequestConfig<any>,
      httpClient: HttpClient,
  ) {
    const mockData = Mock.mock(
        this.mockTemplate(requestConfig, httpClient.mockConfig),
    );
    return handleResponseFulfilled.bind(httpClient)(
        this.createMockTemplateAxiosResponse(mockData, httpClient.requestConfig),
    );
  },
};
